package com.coment.game.fight;

import com.coment.cfg.luban.Tables;
import com.coment.cfg.luban.constant.AIDCFG;
import com.coment.cfg.luban.roles.CardStarCfg;
import com.coment.cfg.luban.roles.NumericalConfig;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/// 属性成分
@Slf4j
public final class Attribute {
    public static Attrs obtainCardAttrs(int userInfoId, int cardId, int lv, Attrs value) {
        Function<Integer, Attrs> obtainAttrsGHandler = AttributeManagerLogic.obtainAttrsGHandler;
        if (obtainAttrsGHandler != null) {
            Attrs attrsG = obtainAttrsGHandler.apply(userInfoId);
//            log.info("全局属性:{}", Attribute.getLogInfo(attrsG));
            value.putAll(attrsG);
        }


        Attrs map = Attribute.obtainRolesATTR_1(cardId, lv, value);

        Attrs rolesLvAttrs = AttributeManagerLogic.ROLES_ATTRS_LV.get(lv);
        if (rolesLvAttrs != null) {
            map.putAll(rolesLvAttrs);
        }

        Attrs rolesCardsAttrs = AttributeManagerLogic.ROLES_TC.get(cardId);
        if (rolesCardsAttrs != null) {
            map.putAll(rolesCardsAttrs);
        }

        map.putAll(value);

        obtainXTQYValue(cardId, lv).forEach((k, v) -> {
            map.merge(k, v, Double::sum);
        });

        return map;
    }


    /**
     * 获取 一级属性
     *
     * @param cardId 卡牌id
     * @param lv     等级
     * @param value  属性  A AG
     * @return 属性
     */
    public static Attrs obtainRolesATTR_1(
            int cardId,
            int lv,
            Attrs value
    ) {
        Attrs res = new Attrs();


        Attrs ROLES_ATTRS_LV_VALUES;

        if (cardId < 1000) {
            ROLES_ATTRS_LV_VALUES = AttributeManagerLogic.ROLES_ATTRS_LV.get(lv);
        } else {
            ROLES_ATTRS_LV_VALUES = AttributeManagerLogic.MONSTER_ATTRS.get(cardId);
        }

        Attrs ROLES_TC_VALUES = AttributeManagerLogic.ROLES_TC.getOrDefault(cardId, new Attrs());

        Attrs xtqyValue = obtainXTQYValue(cardId, lv);


        // 处理一级属性
        // 替换原第 xxx 行开始的 forEach 写法
        for (Map.Entry<Integer, Integer[]> entry : AttributeManagerLogic.attrsCfg.entrySet()) {
            Integer id = entry.getKey();
            Integer[] v = entry.getValue();

            // 等级成长值不一定会有
            Integer ATTR_LV_BASE = v[0];

            if (ATTR_LV_BASE == null) {
                res.put(id, Attrs.ATTR_DEFAULT_VALUE.get(id));
                continue; // 此时在 for 循环中，合法使用 continue
            }

            double ATTR_LV_BASE_VALUE = ROLES_ATTRS_LV_VALUES.get(ATTR_LV_BASE);
            ATTR_LV_BASE_VALUE += value.getOrDefault(ATTR_LV_BASE, 0D);

            Integer ROLES_T = v[4];
            double ROLES_T_VALUE = ROLES_TC_VALUES.getOrDefault(ROLES_T, 1D);
            ROLES_T_VALUE += xtqyValue.getOrDefault(ROLES_T, 0D);
            ROLES_T_VALUE += xtqyValue.getOrDefault(AIDCFG.talentAll, 0D);

            // 处理 + * 区数值
            Integer ATTR_BASE_ADD = v[2];
            double ATTR_BASE_ADD_VALUE = ATTR_BASE_ADD == null ? 0.0 : value.get(ATTR_BASE_ADD) == null ? 0.0 : value.get(ATTR_BASE_ADD);
            ATTR_BASE_ADD_VALUE += xtqyValue.getOrDefault(ATTR_BASE_ADD, 0D);

            Integer ATTR_BASE_M = v[3];
            double ATTR_BASE_M_VALUE = ATTR_BASE_M == null ? 0.0 : value.get(ATTR_BASE_M) == null ? 0.0 : value.get(ATTR_BASE_M);
            ATTR_BASE_M_VALUE *= xtqyValue.getOrDefault(ATTR_BASE_M, 1.0);

            // 处理全局数值
            Integer ATTR_BASE_AG = v[12];
            double ATTR_BASE_AG_VALUE = ATTR_BASE_AG == null ? 0.0 : value.get(ATTR_BASE_AG) == null ? 0.0 : value.get(ATTR_BASE_AG);
            ATTR_BASE_ADD_VALUE += ATTR_BASE_AG_VALUE;

            Integer ATTR_BASE_MAG = v[13];
            double ATTR_BASE_MAG_VALUE = ATTR_BASE_MAG == null ? 0.0 : value.get(ATTR_BASE_MAG) == null ? 0.0 : value.get(ATTR_BASE_MAG);
            ATTR_BASE_M_VALUE += ATTR_BASE_MAG_VALUE;

            double ATTR_1_VALUE = (ATTR_LV_BASE_VALUE * ROLES_T_VALUE + ATTR_BASE_ADD_VALUE) * (1 + ATTR_BASE_M_VALUE);
            res.put(id, ATTR_1_VALUE);
        }

        return res;
    }

    /// 获取 先天气运 属性
    public static Attrs obtainXTQYValue(int cardId, double lv) {
        Attrs value = new Attrs();
        Map<Integer, Attrs> integerMapMap = AttributeManagerLogic.CARD_XTQY_CFG.get(cardId);

        if (integerMapMap == null) {
            return value;
        }

        integerMapMap.forEach((needLV, v) -> {
            if (lv >= needLV) {
                v.forEach((id, v1) -> value.merge(id, v1, Double::sum));
            }
        });
        return value;
    }

    /// 获取角色星级属性
    public static Attrs obtainRolesStarValue(int cardId, Double star) {
        Attrs res = new Attrs();
        if (cardId < 1000) {
            CardStarCfg cardStarCfg = Tables.cfg.get_tbcardstarcfg().get(cardId);
            if (Optional.ofNullable(cardStarCfg).isEmpty()) {
                return res;
            }

            Integer attr = AttributeManagerLogic.constantsMap.get(cardStarCfg.attr);
            double value = cardStarCfg.value * star / Attrs.NUMBER_TYPE.get(attr);
            res.put(attr, value);
        }
        return res;
    }

    public static void log(Logger log, Map<Integer, Double> value) {
        StringBuilder logInfo = getLogInfo(value);
        log.debug(logInfo.toString());
    }

    public static StringBuilder getLogInfo(Map<Integer, Double> value) {
        StringBuilder logInfo = new StringBuilder();
        logInfo.append("\n┌─ 属性详情: %s 共计".formatted(value.size()));

        Map<Integer, Double> safeValueMap = new HashMap<>();
        for (Map.Entry<?, Double> entry : value.entrySet()) {
            if (entry.getKey() instanceof Integer) {
                safeValueMap.put((Integer) entry.getKey(), entry.getValue());
            }
        }
        new TreeMap<>(safeValueMap).forEach((id, attrsValue) -> {
            NumericalConfig numericalConfig = Tables.cfg.get_tbnumericalconfig().get(id);
            String attributeName = numericalConfig.AttributeName;

            if (AttributeManagerLogic.attrsCfg.containsKey(id)) {
                logInfo.append("\n├─ ");
            } else {
                logInfo.append("\n├────");
            }

            // 格式化数值输出，避免显示过多小数位
            String formattedValue;
            if (attrsValue == Math.floor(attrsValue)) {
                // 如果是整数，显示为整数
                formattedValue = String.format("%.0f", attrsValue);
            } else {
                // 如果是小数，保留合适的小数位数
                formattedValue = String.format("%.2f", attrsValue);
            }
            logInfo.append(id).append(".").append(attributeName).append(": ").append(formattedValue);
        });
        logInfo.append("\n└─ ");
        return logInfo;
    }


    @SuppressWarnings("all")
    @SafeVarargs
    public static String eqLog(
            Logger log,
            Attrs... attribute
    ) {
        StringBuilder logInfo = new StringBuilder();
        logInfo.append("\n┌─ 属性详情:");

        // 获取所有属性名称并计算最大长度
        List<String> attributeNames = attribute[0].keySet().stream()
                .map(id -> Tables.cfg.get_tbnumericalconfig().get(id).AttributeName)
                .sorted()
                .toList();

        // 计算属性名的最大长度
        int maxNameLength = attributeNames.stream()
                .mapToInt(String::length)
                .max()
                .orElse(10);

        // 固定数值列宽
        int valueWidth = 10;

        // 按属性名称排序处理
        attribute[0].keySet().stream()
                .map(id -> {
                    NumericalConfig config = Tables.cfg.get_tbnumericalconfig().get(id);
                    return new AbstractMap.SimpleEntry<>(config.AttributeName, id);
                })
                .sorted(Map.Entry.comparingByKey())
                .forEach(entry -> {
                    String attributeName = entry.getKey();
                    Integer id = entry.getValue();

                    if (AttributeManagerLogic.attrsCfg.containsKey(id)) {
                        logInfo.append("\n├─ ");
                    } else {
                        logInfo.append("\n├────");
                    }

                    // 计算属性名的最大长度
                    int maxNameLength1 = attributeNames.stream()
                            .mapToInt(String::length)
                            .max()
                            .orElse(10);

                    logInfo.append(String.format("%-" + maxNameLength1 + "s", attributeName)).append(": ");

                    // 数值右对齐
                    for (Attrs integerDoubleMap : attribute) {
                        Double value = integerDoubleMap.get(id);
                        String valueStr;
                        if (value == Math.floor(value) && !Double.isInfinite(value)) {
                            valueStr = String.format("%.0f", value);
                        } else {
                            valueStr = String.format("%.2f", value);
                        }
                        // 右对齐数值
                        logInfo.append(String.format("%" + valueWidth + "s", valueStr));
                    }
                });
        logInfo.append("\n└─ ");
        log.debug(logInfo.toString());
        return logInfo.toString();
    }

    public static Attrs obtainRolesBaseValue() {
        Map<Integer, Double> collect = Tables.cfg.get_tbnumericalconfig().getDataMap().values().stream()
                .filter(k -> k.effectType == 10)
                .collect(Collectors.toMap(
                        k -> k.NumericalID,
                        v -> v.InitialValue / v.NumType
                ));
        return new Attrs(collect);
    }
}
